package com.gitee.hermer.engine.jars.core.xa.transaction.section;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.atomikos.icatch.CompositeTransaction;
import com.atomikos.icatch.CompositeTransactionManager;
import com.atomikos.icatch.HeurHazardException;
import com.atomikos.icatch.HeurMixedException;
import com.atomikos.icatch.HeurRollbackException;
import com.atomikos.icatch.RollbackException;
import com.atomikos.icatch.SysException;
import com.atomikos.icatch.config.Configuration;
import com.gitee.hermer.boot.jee.commons.log.UtilsContext;
import com.gitee.hermer.boot.jee.commons.verify.Assert;
import com.gitee.hermer.engine.jars.core.context.domain.EngineAppInfoContext;
import com.gitee.hermer.engine.jars.core.domain.EngineConstant;
import com.gitee.hermer.engine.jars.core.execute.EngineExecuteThread;
import com.gitee.hermer.engine.jars.core.execute.IEngineExecuteSection;

@Component()
@Scope(EngineConstant.SPRING_SCOPE_PROTOTYPE)
public class XATransactionEngineExecuteSection extends UtilsContext implements IEngineExecuteSection{


	protected CompositeTransactionManager transactionManager;
	protected CompositeTransaction currTran;
	protected CompositeTransaction subTran;

	@Override
	public void afterPropertiesSet() throws Exception {

	}


	@Override
	public void begin(EngineAppInfoContext appContext) {
		try{
			transactionManager = Configuration.getCompositeTransactionManager();
			Assert.notNull(transactionManager);
			currTran = transactionManager.getCompositeTransaction();
			if(currTran != null)
				subTran = currTran.createSubTransaction();
		}catch (Exception e) {
			error(e.getMessage(),e);
		}
	}

	@Override
	public void beginExecuteThread(EngineExecuteThread executeThread) {
		try {
			if(subTran != null)
				transactionManager.resume(subTran);
		} catch (Exception e) {
			error(e.getMessage(),e);
		} 

	}

	@Override
	public void endExecuteThread(EngineExecuteThread executeThread) {
		if(subTran != null){
			try {
				subTran.commit();
			} catch (HeurRollbackException | HeurMixedException | HeurHazardException | SysException | SecurityException
					| RollbackException e) {
				error(e.getMessage(),e);
			}
		}
	}

	@Override
	public void end(EngineAppInfoContext appContext) {
		subTran = null;
		currTran = null;
	}


	@Override
	public void destroy() throws Exception {
	}

}
